package com.ylink.yfa4j.server.rpc;

import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import javax.sql.DataSource;

import org.springframework.http.HttpMethod;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sca4cloud.sca.common.core.util.SpringContextHolder;

import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * 
 * @author lmc
 * @date 2020/04/30
 */
@Slf4j
public class RpcService {
	//通讯前置服务名
	private final static String YFECOMM_SERVICENAME="sca-commservice";

    @SuppressWarnings("unchecked")
    public Map<String, Object> invokeRpc(String serviceName, String appName, String busCode, Map<String, Object> busdata) {
        Map<String, Object> mapResp = null;
        try {
            RestTemplate restTemplate = SpringContextHolder.getBean("balancedTemplate");
            String strUrl = "http://" + serviceName + "/doBusiness/" + appName + "/" + busCode;
            mapResp = restTemplate.postForObject(strUrl, busdata==null?new HashMap<String, Object>():busdata, Map.class);
        } catch (Exception e) {
            log.error("RSXX0007:" + e.getMessage(), e);
        }
        return mapResp;
    }
    @SuppressWarnings("unchecked")
    public Map<String, Object> invokeRpcUrl(String serviceUrl, String appName, String busCode,
        Map<String, Object> busdata) {
        Map<String, Object> mapResp = null;
        try {
            RestTemplate restTemplate = SpringContextHolder.getBean("singleTemplate");
            String urlhead = "";
            if (serviceUrl.startsWith("http://")) {
                urlhead = serviceUrl;
            } else {
                urlhead = "http://" + serviceUrl;
            }
            String strUrl = urlhead + "/doBusiness/" + appName + "/" + busCode;
            mapResp = restTemplate.postForObject(strUrl, busdata == null ? new HashMap<String, Object>() : busdata,
                Map.class);
        } catch (Exception e) {
            log.error("RSXX0007:" + e.getMessage(), e);
        }
        return mapResp;
    }

    /**
     * <b>方法描述：</b> 调用第三方Rest接口 <br/>
     * <b>创建者：</b> 喻洪乾 <br/>
     * <b>创建时间：</b> 2019年4月17日 上午11:58:31 <br/>
     *
     * @param url
     *            inPara 输入参数
     * @return Rest接口返回
     * @throws Exception
     */
    @SuppressWarnings("unchecked")
    public Object invokeOuterBusiness(String strUrl, Object reqPara) throws Exception {
        Object retObj = null;
        if (StrUtil.isEmpty(strUrl)) {
            log.error("RSXX0011:第三方Rest接口地址不能为空");
            throw new Exception("第三方Rest接口地址不能为空");
        }
        RestTemplate restTemplate = SpringContextHolder.getBean("balancedTemplate");
        if (!strUrl.startsWith("http")) {
            strUrl = "http://" + strUrl;
        }
        // retObj = restTemplate.postForObject(strUrl, reqPara, Object.class);

        MultiValueMap<String, String> headers = new LinkedMultiValueMap<String, String>();
        headers.add("Accept", "text/html,application/json");
        headers.add("Content-Type", "application/json");
        headers.add("Accept-Charset", "UTF-8");

        RequestEntity requestEntity = new RequestEntity(reqPara, headers, HttpMethod.POST, (new URL(strUrl)).toURI());
        ResponseEntity<String> responseEntity = restTemplate.exchange(requestEntity, String.class);
        retObj = responseEntity.getBody();
        if (retObj != null) {
            String retStr = retObj.toString();
            if (retStr.startsWith("{") && retStr.endsWith("}")) {
                try {
                    ObjectMapper objectMapper = new ObjectMapper();
                    retObj = objectMapper.readValue(retStr, Map.class);
                } catch (Exception ex) {
                }
            }
        }
        return retObj;
    }
    /**
     * <b>方法描述：</b> 通讯前置三方调用 <br/>
     * <b>创建者：</b> 于建军 <br/>
     * <b>创建时间：</b> 2018年5月17日 下午3:57:10 <br/>
     *
     * @param busdata 业务数据
     * @return
     */
    @SuppressWarnings("unchecked")
    public Map<String, Object> invokeYfeTransProc(Map<String, Object> busdata) {
      Map<String, Object> mapResp = null;
      try {
        RestTemplate restTemplate = SpringContextHolder.getBean("balancedTemplate");
        String strUrl = "http://" + YFECOMM_SERVICENAME + "/yfasvc/yfeTransProc";
        mapResp = restTemplate.postForObject(strUrl, busdata, Map.class);
      } catch (Exception e) {
        log.error("RSXX0008:" + e.getMessage(), e);
      }
      return mapResp;
    }
    

    /**
     * <b>方法描述：</b> 调用通讯前置组包报文 <br/>
     * <b>创建者：</b> 于建军 <br/>
     * <b>创建时间：</b> 2018年5月23日 上午11:41:31 <br/>
     *
     * @param paraMap 业务数据 system --系统编码 group --分组编号 transCode --交易码 request --待组包字段集
     * @return 组包结果BASE64编码
     */
    public String invokeYfePackMsg(Map<String, Object> paraMap) {
      String respStr = "";
      try {
        RestTemplate restTemplate = SpringContextHolder.getBean("balancedTemplate");
        String strUrl = "http://" + YFECOMM_SERVICENAME + "/yfasvc/yfePackMsg";
        respStr = restTemplate.postForObject(strUrl, paraMap, String.class);
      } catch (Exception e) {
        log.error("RSXX0009:" + e.getMessage(), e);
      }
      return respStr;
    }

    /**
     * <b>方法描述：</b> 调用通讯前置解包报文 <br/>
     * <b>创建者：</b> 于建军 <br/>
     * <b>创建时间：</b> 2018年5月23日 上午11:41:31 <br/>
     *
     * @param paraMap 业务数据 system--分组编号 transCode --交易码 request --待解包报文BASE64编码
     * @return 解包字段集
     */
    @SuppressWarnings("unchecked")
    public Map<String, Object> invokeYfeUnPackMsg(Map<String, Object> paraMap) {
      Map<String, Object> mapResp = null;
      try {
        RestTemplate restTemplate = SpringContextHolder.getBean("balancedTemplate");
        String strUrl = "http://" + YFECOMM_SERVICENAME + "/yfasvc/yfeUnPackMsg";
        mapResp = restTemplate.postForObject(strUrl, paraMap, Map.class);
      } catch (Exception e) {
        log.error("RSXX0010:" + e.getMessage(), e);
      }
      return mapResp;
    }


    public Object getBean(String name) {
    	Object obj=	null;
    	
    	String[] bs=SpringContextHolder.getBeans();
    	for (String b : bs) {
//			log.info(b);
    		if(b.equalsIgnoreCase(name))
    			name=b;
		}
    	try {
    		obj=SpringContextHolder.getBean(name);
		} catch (Exception e) {
		log.error("{}",e);
		}
    	
    
        return obj;
    }

    public DataSource getDataSource(String db) {
        DynamicRoutingDataSource ds = SpringContextHolder.getBean(DynamicRoutingDataSource.class);
        if (StrUtil.isBlank(db))
            return ds.determineDataSource();
        return ds.getDataSource(db);
    }

    public void setDynamicDataSourceContext(String dbName) {
        DynamicDataSourceContextHolder.push(dbName);
    }
}
